package com.example.gateway.cluster;
import com.example.gateway.listener.RegistrationCenterChangeEventListener;
import io.netty.channel.Channel;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.*;

/**
 * @author 谢飞机
 * @date 2021-09-01
 */

public class ClusterManager {

    private final Object LOCK_OBJECT = new Object();

    private final Log log = LogFactory.getLog(RegistrationCenterChangeEventListener.class);

    /**
     * map 最大长度65535
     * key     Ip
     * value   ServerNode
     */
    private volatile TreeMap<String, ServerNode> hashLoopMap = new TreeMap<>();


    public Map<String, ServerNode> getHashLoopMap() {

        synchronized (LOCK_OBJECT) {
            return hashLoopMap;
        }

    }


    /**
     * 刷新hash环 同步
     *
     * @param activeIpList 活跃的serverInstance
     */
    public void refresh(List<String> activeIpList) {

        log.info("- - - - - - - - - 更新Hash环开始 - - - - - - - - - ");

        //按照IP 排序
        Collections.sort(activeIpList, Comparator.comparing(v -> v));

        synchronized (LOCK_OBJECT) {
            //先删后增
            hashLoopMap.clear();

            activeIpList.forEach((ip) -> hashLoopMap.put(

                    ip, ServerNode.builder().host(ip).build()
            ));

        }

        log.info("- - - - - - - - - 更新Hash环结束 - - - - - - - - - ");

        //log.info("- - - - - - - - - 将更新后的Hash环发送服务实例进行更新 - - - - - - - - - ");

    }

    public Channel setChannel(Channel channel, String serverInstanceHost, String clientId) {

        getHashLoopMap()
                .get(serverInstanceHost)
                .getHashLoopEntryMap()
                .get(clientId)
                .setChannel(channel);

        return channel;

    }

    /**
     * 客户端下线处理
     * @param serverInstanceHost
     * @param clientId
     */
    public void channelCloseHandle(String serverInstanceHost, String clientId) {

        log.info("- - - - - - - - - " + clientId + " offline from server " + serverInstanceHost + "  - - - - - - - - - ");
        getHashLoopMap()
                .get(serverInstanceHost)
                .getHashLoopEntryMap()
                .remove(clientId);

    }

}

